import { Client } from 'ssh2'
import archiver from 'archiver'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

const ZIP_FILE = path.resolve(__dirname, 'nuxt_shop.zip') // 打包输出文件
const SERVER_USER = 'root'
const SERVER_IP = '47.120.1.66'
const SERVER_PROJECT_DIR = '/home/shuwang/nuxt_shop'
const PRIVATE_KEY_PATH = path.resolve(__dirname, './shuwang.pem') // 私钥路径，若用密码，改成 password 属性

// 1. 打包当前目录（排除 node_modules 和压缩包自身）
function zipProject() {
  return new Promise((resolve, reject) => {
    console.log('开始打包zip')
    const output = fs.createWriteStream(ZIP_FILE)
    const archive = archiver('zip', { zlib: { level: 9 } })

    output.on('close', () => {
      console.log(`✅ 打包完成，大小: ${archive.pointer()} bytes`)
      resolve()
    })
    archive.on('error', err => reject(err))

    archive.pipe(output)
    archive.glob('**/*', {
      ignore: ['node_modules/**', 'nuxt_shop.zip'],
    })
    archive.finalize()
  })
}

// 2. 连接服务器，上传压缩包并执行远程部署命令
function connectAndDeploy() {
  return new Promise((resolve, reject) => {
    const conn = new Client()
    conn
      .on('ready', () => {
        console.log('✅ SSH连接成功，开始上传 zip...')
        conn.sftp((err, sftp) => {
          if (err) return reject(err)
          const remoteZipPath = '/home/shuwang/nuxt_shop.zip'
          sftp.fastPut(ZIP_FILE, remoteZipPath, err => {
            if (err) return reject(err)

            console.log('📤 上传完成，开始远程解压并运行 docker...')
            const cmd = `
              rm -rf ${SERVER_PROJECT_DIR} && \
              mkdir -p ${SERVER_PROJECT_DIR} && \
              unzip -o ${remoteZipPath} -d ${SERVER_PROJECT_DIR} && \
              rm -f ${remoteZipPath} && \
              cd ${SERVER_PROJECT_DIR} && \
              docker rm -f nuxt-app || true && \
              docker build -t nuxt-app . && \
              docker run -d -p 3000:3000 --name nuxt-app nuxt-app
            `
            conn.exec(cmd, (err, stream) => {
              if (err) return reject(err)
              stream
                .on('close', (code, signal) => {
                  console.log(`✅ 部署完成。退出码: ${code}, 信号: ${signal}`)
                  conn.end()
                  resolve()
                })
                .on('data', data => process.stdout.write(data))
                .stderr.on('data', data => process.stderr.write(data))
            })
          })
        })
      })
      .on('error', err => reject(err))
      .connect({
        host: SERVER_IP,
        port: 22,
        username: SERVER_USER,
        privateKey: fs.readFileSync(PRIVATE_KEY_PATH),
        // 如果用密码，改为： password: '你的密码',
      })
  })
}

// 3. 主流程：先打包，再部署
async function deploy() {
  try {
    await zipProject()
    await connectAndDeploy()
  } catch (error) {
    console.error('❌ 部署失败:', error)
    process.exit(1)
  }
}

deploy()